using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Objects;
using System.Linq;
using Magiq.Providers.Entities;
using Magiq.Tests.Support;

namespace Magiq.Tests.Entities
{
    public class MagiqToEntitiesTestConfigurator : IMagiqTestConfigurator
    {
        public ObjectContext ObjectContext { get; private set; }

        static MagiqToEntitiesTestConfigurator()
        {
            Current = new MagiqToEntitiesTestConfigurator();
        }

        private MagiqToEntitiesTestConfigurator()
        {
        }

        public static MagiqToEntitiesTestConfigurator Current { get; private set; }

        #region IMagiqTestConfigurator Members

        public void Persist<T>(IList<T> items) where T : class
        {
            foreach (var item in items)
                ObjectContext.CreateObjectSet<T>().AddObject(item);
        }

        public void SetUp()
        {
            MagiqConfigurator.Clear()
                .Register<MagiqMock>()
                .Register<MagiqToEntities>();

            CreateObjectContext();

            if (ObjectContext.DatabaseExists())
                ObjectContext.DeleteDatabase();
            ObjectContext.CreateDatabase();
        }

        public void TearDown()
        {
            CloseObjectContext();
        }

        public IQueryable<T> GetQueryable<T>() where T : class
        {
            return ObjectContext.CreateObjectSet<T>();
        }
        
        public void Reload()
        {
            ObjectContext.DetectChanges();
            ObjectContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
            CloseObjectContext();
            CreateObjectContext();
        }

        #endregion
        
        private void CreateObjectContext()
        {

            ObjectContext =
                new ObjectContext(ConfigurationManager.ConnectionStrings["TestModelContainer"].ConnectionString);
            ObjectContext.ContextOptions.LazyLoadingEnabled = true;
            ObjectContext.ContextOptions.ProxyCreationEnabled = true;
        }

        private void CloseObjectContext()
        {
            var c = ObjectContext.Connection;
            if (c.State != ConnectionState.Closed)
                c.Close();
            ObjectContext.Dispose();
            c.Dispose();
        }
    }
}